package com.rui.study.micro.gateway.filter;

import com.rui.study.commons.util.JwtUtil;
import com.rui.study.commons.util.StringUtil;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.*;

/**
 * @program: study
 * @description:
 * @author: Yaowr
 * @create: 2019-02-14 12:04
 **/
@Component
@RefreshScope
public class SecureFilter implements GlobalFilter, Ordered {

    private static final String ACCESS_TOKEN = "access_token";


    protected List<String> publics;
    protected Map<String, String> publicsMethod;
    private PathMatcher matcher = new AntPathMatcher();



    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("进入 Filter");
        ServerHttpRequest serverHttpRequest = exchange.getRequest();
        System.out.println(serverHttpRequest.getMethodValue());
        if (isFreeUrls(serverHttpRequest.getURI().getPath(), serverHttpRequest.getMethodValue())) {
            return chain.filter(exchange);
        }
//        for (Map.Entry<String, Object> entry : exchange.getAttributes().entrySet()) {
//            System.out.println(entry.getKey() + " = " + entry.getValue());
//        }
//        System.out.println("-----------");
//        for (Map.Entry<String, List<String>> entry : exchange.getRequest().getHeaders().entrySet()) {
//            System.out.println(entry.getKey() + " = " + entry.getValue());
//        }
        List<String> accessTokenList = serverHttpRequest.getHeaders().get("access_token");
        if (accessTokenList == null || accessTokenList.size() == 0
                || StringUtil.isEmpty(accessTokenList.get(0))) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }

        try {
            String token = String.valueOf(accessTokenList.get(0));
            Claims claims = JwtUtil.parse(token, null);
        } catch (Exception e) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }


        return chain.filter(exchange);
    }


    @Value("${gateway.free.urls:}")
    private void setPublics(String urls) {
        String[] _urls = urls.split(",");
        publics = new ArrayList<>(0);
        publicsMethod = new Hashtable<>(0);
        for (String url : _urls) {
            url = url.trim();
            if (url.length() == 0) {
                continue;
            }
            String[] split = url.split(" ");
            if (split.length == 1) {
                publics.add(url);
                continue;
            }
            publics.add(split[1]);
            publicsMethod.put(split[1], split[0].toUpperCase());
        }
    }
    private boolean isFreeUrls(String requestURL, String method) {
        if (publics == null) return false;
        //判断该请求是不是公开访问的
        Iterator<String> iterator = publics.iterator();
        while (iterator.hasNext()) {
            String next = iterator.next();
            if (matcher.match(next, requestURL)) {
                if (!publicsMethod.containsKey(next) || publicsMethod.get
                        (next).contains(method)) {
                    return true;
                }
            }
        }
        return false;
    }
}
